package config

import (
	"os"
	"strconv"
	"strings"
)

type Config struct {
	DBHost     string
	DBPort     int
	DBName     string
	DBUser     string
	DBPassword string

	RedisHost     string
	RedisPort     int
	RedisPassword string
	RedisDB       int

	MQTTHost   string
	MQTTPort   int
	MQTTWSPort int

	JWTSecret     string
	MQTTSecretKey string

	TelemetryRetentionCount int
	EventsRetentionCount    int

	AppPort  int
	AppEnv   string
	LogLevel string
}

func Load() *Config {
	return &Config{
		DBHost:     getEnv("DB_HOST", "localhost"),
		DBPort:     getEnvAsInt("DB_PORT", 5432),
		DBName:     getEnv("DB_NAME", "things_iot"),
		DBUser:     getEnv("DB_USER", "postgres"),
		DBPassword: getEnv("DB_PASSWORD", "password"),

		RedisHost:     getEnv("REDIS_HOST", "localhost"),
		RedisPort:     getEnvAsInt("REDIS_PORT", 6379),
		RedisPassword: getEnv("REDIS_PASSWORD", ""),
		RedisDB:       getEnvAsInt("REDIS_DB", 0),

		MQTTHost:   getEnv("MQTT_HOST", "localhost"),
		MQTTPort:   getEnvAsInt("MQTT_PORT", 1883),
		MQTTWSPort: getEnvAsInt("MQTT_WS_PORT", 8083),

		JWTSecret:     getEnv("JWT_SECRET", "default_jwt_secret"),
		MQTTSecretKey: getEnv("MQTT_SECRET_KEY", "default_mqtt_secret"),

		TelemetryRetentionCount: getEnvAsInt("TELEMETRY_RETENTION_COUNT", 5000),
		EventsRetentionCount:    getEnvAsInt("EVENTS_RETENTION_COUNT", 1000),

		AppPort:  getEnvAsInt("APP_PORT", 8080),
		AppEnv:   getEnv("APP_ENV", "development"),
		LogLevel: getEnv("LOG_LEVEL", "info"),
	}
}

func getEnv(key, defaultValue string) string {
	if value := os.Getenv(key); value != "" {
		return value
	}
	return defaultValue
}

func getEnvAsInt(key string, defaultValue int) int {
	if value := os.Getenv(key); value != "" {
		if intValue, err := strconv.Atoi(value); err == nil {
			return intValue
		}
	}
	return defaultValue
}

func getEnvAsBool(key string, defaultValue bool) bool {
	if value := os.Getenv(key); value != "" {
		if boolValue, err := strconv.ParseBool(value); err == nil {
			return boolValue
		}
	}
	return defaultValue
}

func getEnvAsSlice(key string, defaultValue []string, sep string) []string {
	if value := os.Getenv(key); value != "" {
		return strings.Split(value, sep)
	}
	return defaultValue
}
